package com.online.shopping.config;

import com.online.shopping.common.component.RestAuthenticationEntryPoin;
import com.online.shopping.common.component.RestAuthorizationHandler;
import com.online.shopping.common.filter.JwtAuthenticationFilter;
import com.online.shopping.common.utils.UserDetailImpl;
import com.online.shopping.pojo.TbSeller;
import com.online.shopping.service.TbSellerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.util.ArrayList;
import java.util.Collection;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private TbSellerService tbSellerService;

	@Bean
	@Override
	protected AuthenticationManager authenticationManager() throws Exception {
		return super.authenticationManager();
	}

	@Bean
	public PasswordEncoder passwordEncoder(){
		return new BCryptPasswordEncoder();
	}

	@Bean
	public UserDetailsService userDetailsService(){
		return new UserDetailsService() {
			@Override
			public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
				System.out.println("账号："+username);
				TbSeller user = tbSellerService.findBySellerId(username);

				if(user != null){
					Collection<? extends GrantedAuthority> authorities = new ArrayList<>();
					return new UserDetailImpl(user,authorities);
				}
				throw new UsernameNotFoundException("账号或密码错误！");
			}
		};
	}

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(userDetailsService());
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// cors：配置跨域访问
		// sessionManagement：配置session登录
		// sessionCreationPolicy：设置无状态session登录
		// 然后就是设置除了doLogin以外的请求都拦截
		// addFilterBefore：添加filter
		http.cors()
			.and()
			.sessionManagement()
			.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
			.and()
			.authorizeRequests()
			.antMatchers("/doLogin")
			.permitAll()
			.anyRequest()
			.authenticated()
			.and()
			.addFilterBefore(new JwtAuthenticationFilter("/doLogin",authenticationManager()), UsernamePasswordAuthenticationFilter.class);   // 用户的登录认证，回调
//			.addFilterBefore(new JwtAuthorizationFilter(),UsernamePasswordAuthenticationFilter.class);  // 资源的拦截认证

		// 禁用CSRF防御
		http.csrf().disable();

		// 报错的处理组件
		http.exceptionHandling().accessDeniedHandler(new RestAuthorizationHandler())
								.authenticationEntryPoint(new RestAuthenticationEntryPoin());
	}
}
